package com.enjoyor.soa.traffic.ping.efoms.dubbo;

import com.enjoyor.soa.traffic.api.dto.efoms.PingResultDto;
import com.enjoyor.soa.traffic.core.ping.domain.DevStatusInfo;
import com.enjoyor.soa.traffic.core.ping.enums.EnumDicPublic;
import com.enjoyor.soa.traffic.core.ping.service.IDevStatusInfoService;
import com.enjoyor.soa.traffic.ping.efoms.common.Global;
import com.enjoyor.soa.traffic.ping.efoms.pojo.MessagePushEventPojo;
import com.enjoyor.soa.traffic.ping.efoms.pojo.PingResultPojo;
import com.enjoyor.soa.traffic.util.helper.ReflectHelper;
import com.enjoyor.soa.traffic.util.helper.TimeHelper;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.List;

/**
 *
 * 事件监听
 * @ClassNamePushMsg
 * @Description TODO
 * @Author ZSY
 * @Date 2019/1/17 10:07
 * @Version 1.0
 **/
@Service
public class AnalysisListenerServer implements ApplicationListener<MessagePushEventPojo> {

    @Value("${ping.times.low}")
    private int lowTimes;

    @Value("${ping.times.heigh}")
    private int heighTimes;
    
    @Value("${ping.send.size}")
    private int sendSize;

    @Value("${ping.result.file.isSave}")
    private Boolean pingFileIsSave;
    
    @Value("${ping.result.file.dir}")
    private String pingFileDir;
    
    @Value("${ping.server.signal.isSave}")
    private Boolean signalIsSave;
    
    @Value("${ping.server.system}")
    private String pingSystem;
    
    @Autowired
    private IDevStatusInfoService devStatusInfoService;

    /**
     * 异步执行事件监听
     * @param event
     */
    @Override
    @Async
    public void onApplicationEvent(MessagePushEventPojo event) {
        PingResultPojo pingResultPojo = event.getPingResultPojo();
        if(pingResultPojo!=null){
        	//判断系统类型
        	if("linux".equals(pingSystem)) {
        		pingResultPojo = analysisInfoLinux(pingResultPojo);
        	}else {
        		pingResultPojo = analysisInfoWindows(pingResultPojo);
        	}
            PingResultDto pingResultDto = ReflectHelper.beanToBean(pingResultPojo, PingResultDto.class);
            //内存保存推送数据
            Global.resultQueue.add(pingResultDto);
            
            //存储到数据库（九江信号机使用）
            if(signalIsSave) {
            	DevStatusInfo devStatusInfo = new DevStatusInfo();
                devStatusInfo.setDevId(pingResultPojo.getDevId());
                if(EnumDicPublic.DEVICE_STATUS_USE.getKey().equals(pingResultPojo.getDevStatus())) {
                	if(pingResultPojo.getLossPacketRate() >= 0 && pingResultPojo.getLossPacketRate() < 1) {
                    	devStatusInfo.setDevStatus("1");
                    }else if(pingResultPojo.getLossPacketRate() == 1) {
                    	devStatusInfo.setDevStatus("2");
                    }else {
                    	devStatusInfo.setDevStatus("3");
                    }
                }else {
                	devStatusInfo.setDevStatus("4");
                }
                devStatusInfo.setUpdateTime(TimeHelper.dateToLongString());
                String devId = devStatusInfoService.synDevStatusInfo(devStatusInfo);
            }
            //String devIdSbjk = devStatusInfoService.updateSbjkDevStatus(devStatusInfo);
            //System.out.println(pingResultPojo);
            if(pingFileIsSave) {
            	try { 
                	File writeName = new File(pingFileDir); // 相对路径，如果没有则要建立一个新的pingResult.txt文件 
                	if (!writeName.getParentFile().exists()) {
                		writeName.getParentFile().mkdirs();
                    }
                	writeName.createNewFile(); // 创建新文件,有同名的文件的话直接覆盖 
    		    	FileOutputStream fos = null;
    		    	if(!writeName.exists()){ 
    		    		writeName.createNewFile();//如果文件不存在，就创建该文件 
    		    		fos = new FileOutputStream(writeName);//首次写入获取 
    		    	}else{ 
    		    		//如果文件已存在，那么就在文件末尾追加写入 
    		    		fos = new FileOutputStream(writeName,true);//这里构造方法多了一个参数true,表示在文件末尾追加写入 
    		    	}
    		    	OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF-8");//指定以UTF-8格式写入文件
    		    	osw.write(pingResultPojo.toString()+"\r\n"); // \r\n即为换行 
            		osw.close(); // 写入完成关闭流
    		    } catch (IOException e) { 
    		    	e.printStackTrace(); 
    		    }
            }
        }
        //System.out.println(pingResultPojo);
    }
    /**
     * 分析ping结果windows
     */
    public PingResultPojo analysisInfoWindows(PingResultPojo pingResultPojo)  {
        int times = pingResultPojo.getTimes();
        if (pingResultPojo != null) {
            List<String> result = pingResultPojo.getPingResult();
            if (result != null && result.size() > 0) {
                int length = result.size();
                int time = 0;
                for (String data : result) {
                    String[] cs = data.split(":")[1].substring(1).split(" ");
                    String timeData =cs[1];
                    if(timeData.contains("<")||timeData.contains(">"))
                        timeData = timeData.replace("<","=").replace(">","=");
                    time += Integer.valueOf(timeData.split("=")[1].replace("ms", ""));
                }
                double lossRate = (times - length) / times;
                int avgTime = time / length;
                pingResultPojo.setAvgTime(avgTime);
                pingResultPojo.setLossPacketRate(lossRate);
                if(times < heighTimes && lossRate < 0.4){
                	String key = pingResultPojo.getDevTypeCode() + "-" + pingResultPojo.getDevId();
                	PingResultPojo pingPojo = IPCategoryService.IPPool.get(key);
                	if(null != pingPojo) {
                		pingPojo.setTimes(heighTimes);
                        IPCategoryService.IPPool.put(key, pingPojo);
                	}
                }
            } else {
                pingResultPojo.setLossPacketRate(1.00);
                pingResultPojo.setAvgTime(0);
                if(times==heighTimes){
                	String key = pingResultPojo.getDevTypeCode() + "-" + pingResultPojo.getDevId();
                	PingResultPojo pingPojo = IPCategoryService.IPPool.get(key);
                	if(null != pingPojo) {
                		pingPojo.setTimes(lowTimes);
                        IPCategoryService.IPPool.put(key, pingPojo);
                	}
                }
            }
            return pingResultPojo;
        }else {
            return null;
        }
    }
    /**
     * 分析ping结果linux
     */
    public PingResultPojo analysisInfoLinux(PingResultPojo pingResultPojo)  {
        int times = pingResultPojo.getTimes();
        if (pingResultPojo != null) {
            List<String> result = pingResultPojo.getPingResult();
            //System.out.println("\n result.size()====="+result.size());
            if (result != null && result.size() > 0) {
            	//System.out.println("\n result.size(0)====="+result.get(0));
                int length = result.size();
                double time = 0;
                for (String data : result) {
                	String dataSub = data.split("time=")[1];
                    //String[] cs = data.split("time=")[1].substring(0,).split(" ");
                    String timeData = dataSub.substring(0, dataSub.indexOf(" "));
                    //if(timeData.contains("<")||timeData.contains(">"))
                    //    timeData = timeData.replace("<","=").replace(">","=");
                    time += Double.valueOf(timeData);
                }
                double lossRate = (times - length) / times;
                double avgTime = time / length;
                pingResultPojo.setAvgTime((int)avgTime);
                pingResultPojo.setLossPacketRate(lossRate);
                if(times < heighTimes && lossRate < 0.4){
                	String key = pingResultPojo.getDevTypeCode() + "-" + pingResultPojo.getDevId();
                	PingResultPojo pingPojo = IPCategoryService.IPPool.get(key);
                	if(null != pingPojo) {
                		pingPojo.setTimes(heighTimes);
                        IPCategoryService.IPPool.put(key, pingPojo);
                	}
                }
            } else {
                pingResultPojo.setLossPacketRate(1.00);
                pingResultPojo.setAvgTime(0);
                if(times==heighTimes){
                	String key = pingResultPojo.getDevTypeCode() + "-" + pingResultPojo.getDevId();
                	PingResultPojo pingPojo = IPCategoryService.IPPool.get(key);
                	if(null != pingPojo) {
                		pingPojo.setTimes(lowTimes);
                        IPCategoryService.IPPool.put(key, pingPojo);
                	}
                }
            }
            return pingResultPojo;
        }else {
            return null;
        }
    }

}
